fix(install): copy dylib dependencies alongside binaries (#17055)#17078
fix(install): copy dylib dependencies alongside binaries (#17055)#17078sximelon wants to merge 1 commit into
Conversation
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ehuss (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
Why was this reviewer chosen?The reviewer was selected based on:
|
d9d7ad9 to
ad5146e
Compare
|
Our contrib ask for issues to be the focus for problem and solution exploration with PRs for implementation discussions. Since the Issue is not |
|
I've investigated this and put together a fix at #17078. Here's what I found: Root cause: cargo install only copies the binary to ~/.cargo/bin/, ignoring any .so/.dylib files the binary depends on. The Compilation struct already tracks cdylibs (and I added the missing dylibs field), but cargo_install.rs never uses them. The fix has two parts:
What I tried and why it didn't work:
Would appreciate guidance on whether this approach looks reasonable. |
|
@sximelon please discuss in the issue, and I wanted to say this is not a trivial features that we should also look like prior arts from other systems, and then decide how Cargo handles dylibs installation. |
What does this PR try to resolve?
Fixes #17055.
When a crate depends on a dylib or cdylib, rustc implicitly enables -C prefer-dynamic, which causes libstd to be linked as a shared library. cargo install only copies the binary to ~/.cargo/bin/, leaving the required .so files behind, so the binary fails at runtime.
This PR addresses the issue with two changes:
Copy shared libraries alongside the binary — a new install_dylibs() function collects .so/.dylib files from three sources: root-unit cdylib/dylib targets, a directory scan of root_output and deps_output (for dependency crates), and the sysroot target libdir (for libstd).
Fix rpath after install — fix_rpath_for_install() adds $ORIGIN (Linux, via patchelf) or @loader_path (macOS, via install_name_tool) to the installed binary's rpath, so it can find the shared libraries in its own directory. If the tool is not available, a warning is emitted.
How to test and review this PR?
cargo build --bin cargo./target/debug/cargo install --force cargo_install_dylib_buglibstd and project dylibs should be installed alongside the binary
ls ~/.cargo/bin/*.soIf patchelf is installed, the binary should work:
cargo_install_dylib_bugif patchelf is not installed:
LD_LIBRARY_PATH=~/.cargo/bin cargo_install_dylib_bug